﻿using System;
using System.Collections.Generic;
using System.Text;

using System.ComponentModel;
using System.Data;
using System.Web;

using XCode;
using XCode.Attributes;
using XCode.Entity;
using XCode.DataAccessLayer;
using XCode.Configuration;

namespace XCMSData
{
	/// <summary>
	/// 栏目
	/// </summary>
	[Serializable]
	[DataObject]
	[Description("栏目")]
	[BindTable("X_Board", Description = "栏目", ConnName = "XCMS")]
	public partial class Board
	{
		#region 数据操作对象
		private static DAL _EntityDBO;
		private static Object __EntityDBO_Lock = new Object();
		/// <summary>
		/// 一个数据库就只有一个DAL对象。
		/// 可在运行时设置该实体的数据库。
		/// 更新Config是为了使得Entity基类中的静态方法使用该实体的数据操作对象
		/// </summary>
		public static DAL EntityDBO
		{
			get
			{
				if (_EntityDBO != null) return _EntityDBO;
				lock (__EntityDBO_Lock)
				{
					if (_EntityDBO != null) return _EntityDBO;
					// 从属性配置中取得连接名，使得本实体能用于某些不能写用户代码的场合（比如ObjectDataSource绑定）
					if (!String.IsNullOrEmpty(Config.ConnName(typeof(Board))))
						_EntityDBO = DAL.Create(Config.ConnName(typeof(Board)));
					else
						_EntityDBO = DBO;
					return _EntityDBO;
				}
			}
			set
			{
				_EntityDBO = value;
			}
		}

		[ThreadStatic]
		private static DAL _SessionDBO;
		/// <summary>
		/// 这是用于静态方法的DAL，如果没有设置则使用EntityDBO
		/// </summary>
		public static DAL SessionDBO
		{
			get
			{
				if (HttpContext.Current == null)
				{
					if (_SessionDBO != null) return _SessionDBO;
				}
				else
				{
					DAL d = HttpContext.Current.Items["SessionDBO_Board"] as DAL;
					if (d != null) return d;
				}
				return EntityDBO;
			}
			set
			{
				if (HttpContext.Current == null)
					_SessionDBO = value;
				else
					HttpContext.Current.Items["SessionDBO_Board"] = value;
			}
		}
		#endregion

		#region DAL操作
		/// <summary>
		/// 执行
		/// </summary>
		/// <param name="sql"></param>
		/// <returns></returns>
		protected static int Execute(String sql)
		{
			return Execute(sql, typeof(Board));
		}

		/// <summary>
		/// 查询
		/// </summary>
		/// <param name="sql"></param>
		/// <returns></returns>
		protected static DataSet Query(String sql)
		{
			return Query(sql, typeof(Board));
		}

		/// <summary>
		/// 查询记录数
		/// </summary>
		/// <param name="sql"></param>
		/// <returns></returns>
		protected static int QueryCount(String sql)
		{
			return QueryCount(sql, typeof(Board));
		}
		#endregion

		#region 属性
		private Int32 _ID;
		/// <summary>
		/// 编号
		/// </summary>
		[Description("编号")]
		[DataObjectField(true, true, false, 10)]
		[BindColumn("ID", Description = "编号")]
		public Int32 ID
		{
			get { return _ID; }
			set { _ID = value; }
		}
		
		private String _BoardName;
		/// <summary>
		/// 栏目
		/// </summary>
		[Description("栏目")]
		[DataObjectField(false, false, true, 50)]
		[BindColumn("BoardName", Description = "栏目")]
		public String BoardName
		{
			get { return _BoardName; }
			set { _BoardName = value; }
		}
		
		private Int32 _ParentID;
		/// <summary>
		/// 父栏目
		/// </summary>
		[Description("父栏目")]
		[DataObjectField(false, false, true, 10)]
		[BindColumn("ParentID", Description = "父栏目")]
		public Int32 ParentID
		{
			get { return _ParentID; }
			set { _ParentID = value; }
		}
		
		private Int32 _Order;
		/// <summary>
		/// 排序
		/// </summary>
		[Description("排序")]
		[DataObjectField(false, false, true, 10)]
		[BindColumn("X_Order", Description = "排序")]
		public Int32 Order
		{
			get { return _Order; }
			set { _Order = value; }
		}
		
		private String _Tips;
		/// <summary>
		/// 提示
		/// </summary>
		[Description("提示")]
		[DataObjectField(false, false, true, 255)]
		[BindColumn("Tips", Description = "提示")]
		public String Tips
		{
			get { return _Tips; }
			set { _Tips = value; }
		}
		
		private String _Readme;
		/// <summary>
		/// 备注
		/// </summary>
		[Description("备注")]
		[DataObjectField(false, false, true, 2147483647)]
		[BindColumn("Readme", Description = "备注")]
		public String Readme
		{
			get { return _Readme; }
			set { _Readme = value; }
		}
		#endregion

		#region 构造函数
		/// <summary>
		/// 初始化一个Board实例。
		/// </summary>
		public Board()
		{
			OnInit(1);
		}

		/// <summary>
		/// 初始化一个Board实例。
		/// </summary>
		/// <param name="__BoardName">栏目</param>
		/// <param name="__ParentID">父栏目</param>
		/// <param name="__Order">排序</param>
		/// <param name="__Tips">提示</param>
		/// <param name="__Readme">备注</param>
		public Board(String __BoardName, Int32 __ParentID, Int32 __Order, String __Tips, String __Readme)
		{
			_BoardName = __BoardName;
			_ParentID = __ParentID;
			_Order = __Order;
			_Tips = __Tips;
			_Readme = __Readme;
			OnInit(2);
		}

		/// <summary>
		/// 初始化一个Board实例。根据唯一键ID查询一个栏目实体对象
		/// </summary>
		/// <param name="__ID">唯一键</param>
		public Board(Int32 __ID)
		{
			FindByKey(__ID);
			OnInit(3);
		}
		#endregion

		#region 获取/设置 字段值
		/// <summary>
		/// 获取/设置 字段值。
		/// 一个索引，基类使用反射实现。
		/// 派生实体类可重写该索引，以避免反射带来的性能损耗
		/// </summary>
		/// <param name="name">字段名</param>
		/// <returns></returns>
		public override Object this[String name]
		{
			get
			{
				switch (name)
				{
					case "ID": return ID;
					case "BoardName": return BoardName;
					case "ParentID": return ParentID;
					case "Order": return Order;
					case "Tips": return Tips;
					case "Readme": return Readme;
					default: throw new Exception("类[" + this.GetType().FullName + "]中不存在[" + name + "]属性");
				}
			}
			set
			{
				switch (name)
				{
					case "ID": _ID = Convert.ToInt32(value); break;
					case "BoardName": _BoardName = Convert.ToString(value); break;
					case "ParentID": _ParentID = Convert.ToInt32(value); break;
					case "Order": _Order = Convert.ToInt32(value); break;
					case "Tips": _Tips = Convert.ToString(value); break;
					case "Readme": _Readme = Convert.ToString(value); break;
					default: throw new Exception("类[" + this.GetType().FullName + "]中不存在[" + name + "]属性");
				}
			}
		}
		#endregion

		#region 填充数据
		/// <summary>
		/// 加载记录集
		/// </summary>
		/// <param name="ds">记录集</param>
		/// <returns>实体数组</returns>
		public static IList<Board> LoadData(DataSet ds)
		{
			return LoadData<Board>(ds);
		}

		/// <summary>
		/// 加载数据表
		/// </summary>
		/// <param name="dt">数据表</param>
		/// <returns>实体数组</returns>
		public static IList<Board> LoadData(DataTable dt)
		{
			return LoadData<Board>(dt);
		}
		#endregion

		#region 缓存
		private static Boolean _EnableCache = false;
		/// <summary>
		/// 使用缓存。主要是为了针对FindByKey进行缓存优化。
		/// </summary>
		public static Boolean EnableCache
		{
			get { return _EnableCache; }
			set
			{
				_EnableCache = value;
				_Cache = null;
			}
		}

		/// <summary>
		/// 用于缓存的多线程锁
		/// </summary>
		private static Object _Cache_Lock = new Object();
		/// <summary>
		/// 缓存已经被更新。Cache属性将依赖于该字段对缓存数据进行更新。
		/// </summary>
		private static Boolean hasUpdated = false;
		private static IList<Board> _Cache;
		/// <summary>
		/// 缓存。
		/// </summary>
		public static IList<Board> Cache
		{
			get
			{
				//如果没有启用缓存，就直接返回null。
				if (!EnableCache) return null;

				if (!hasUpdated)
				{
					lock (_Cache_Lock)
					{
						if (!hasUpdated)
						{
							//先取总数，如果总数太大，就是设计上的失误了。
							int count = SelectCount<Board>();
							if (count > 1000) throw new Exception("总记录数超过1000，为了保证服务器稳定运行，禁止使用对象缓存！\n如果出现该错误，可能是程序设计上的问题！");
							//直接调用Entity函数，避免形成缓存死循环
							_Cache = Select<Board>();
							hasUpdated = true;
						}
					}
				}
				return _Cache;
			}
		}

		/// <summary>
		/// 找到一个复合条件的项。不捕获异常，如果发生异常，就是属性名写错了。
		/// </summary>
		/// <param name="names"></param>
		/// <param name="values"></param>
		/// <returns></returns>
		private static Board FindInCache(String[] names, Object[] values)
		{
			if (Cache == null) return null;
			foreach (Board item in Cache)
			{
				for (int i = 0; i < names.Length; i++)
				{
					//if (item[names[i]] == values[i]) return item;
					//不能实用==比较，因为表面是Object，实际上是具体类型，使用Equals可使用具体类型的重载
					if (item[names[i]].Equals(values[i])) return item;
				}
			}
			return null;
		}

		/// <summary>
		/// 找到所有复合条件的项
		/// </summary>
		/// <param name="names"></param>
		/// <param name="values"></param>
		/// <returns></returns>
		private static IList<Board> FindAllInCache(String[] names, Object[] values)
		{
			return FindAllInCache(names, values, 0, -1);
		}


		/// <summary>
		/// 找到所有复合条件的项
		/// </summary>
		/// <param name="names"></param>
		/// <param name="values"></param>
		/// <returns></returns>
		private static IList<Board> FindAllInCache(String[] names, Object[] values, int startRowIndex, int maximumRows)
		{
			if (Cache == null || Cache.Count < 1) return null;

			int start = startRowIndex;
			if (start < 0) start = 0;
			int count = maximumRows;
			if (count > Cache.Count || count <= 0) count = Cache.Count;

			IList<Board> list = null;
			int index = 0;
			foreach (Board item in Cache)
			{
				Boolean match = true;
				if (names != null && names.Length > 0 &&
					!(names.Length == 1 && String.IsNullOrEmpty(names[0])))
				{
					for (int i = 0; i < names.Length; i++)
					{
						//if (item[names[i]] != values[i])
						//不能实用==比较，因为表面是Object，实际上是具体类型，使用Equals可使用具体类型的重载
						if (!item[names[i]].Equals(values[i]))
						{
							match = false;
							break;
						}
					}
				}
				if (match)
				{
					if (index >= start && index < start + count)
					{
						if (list == null) list = new List<Board>();
						list.Add(item);
					}
					index++;
					if (index >= start + count) return list;
				}
			}
			return list;
		}
		#endregion

		#region 主键
		/// <summary>
		/// 根据唯一键ID查询一个栏目实体对象
		/// </summary>
		/// <param name="__ID">唯一键</param>
		/// <returns>栏目 实体对象</returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static Board FindByKey(Int32 __ID)
		{
			if (!EnableCache)
			{
				IList<Board> list = SelectAll(Board._.ID, __ID);
				if (list != null && list.Count > 0) return list[0];
				return null;
			}
			else
				return FindInCache(new String[] { Board._.ID }, new Object[] { __ID });
		}
		#endregion

		#region 外键
		#endregion

		#region 静态操作
		#region 查询
		/// <summary>
		/// 获取所有实体对象。获取大量数据时会非常慢，慎用
		/// </summary>
		/// <returns>栏目 实体数组</returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static IList<Board> SelectAll()
		{
			return EnableCache ? Cache : Select<Board>();
		}

		/// <summary>
		/// 查询并返回试题对象数组。
		/// 表名以及所有字段名，请使用类型已经字段对应的属性名，方法内进行转换
		/// </summary>
		/// <param name="whereClause">条件，不带Where</param>
		/// <param name="orderClause">排序，不带Order By</param>
		/// <param name="selects">查询列</param>
		/// <param name="startRowIndex">起始行，0开始</param>
		/// <param name="maximumRows">最大返回行数</param>
		/// <returns>栏目 实体数组</returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static IList<Board> SelectAll(String whereClause, String orderClause, String selects, int startRowIndex, int maximumRows)
		{
			//如果三个参数都为空，则可以使用缓存
			if (EnableCache && String.IsNullOrEmpty(whereClause) &&
				String.IsNullOrEmpty(orderClause) && String.IsNullOrEmpty(selects))
			{
				return FindAllInCache(null, null, startRowIndex, maximumRows);
			}
			return Select<Board>(whereClause, orderClause, selects, startRowIndex, maximumRows);
		}

		/// <summary>
		/// 根据属性列表以及对应的值列表，获取所有实体对象
		/// </summary>
		/// <param name="names">属性列表</param>
		/// <param name="values">值列表</param>
		/// <returns>栏目 实体数组</returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static IList<Board> SelectAll(String[] names, Object[] values)
		{
			if (EnableCache) return FindAllInCache(names, values);
			return SelectAll(MakeCondition(typeof(Board), names, values, "And"), null, null, 0, 0);
		}

		/// <summary>
		/// 根据属性以及对应的值，获取所有实体对象
		/// </summary>
		/// <param name="name">属性</param>
		/// <param name="value">值</param>
		/// <returns>栏目 实体数组</returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static IList<Board> SelectAll(String name, Object value)
		{
			return SelectAll(new String[] { name }, new Object[] { value });
		}

		/// <summary>
		/// 根据属性以及对应的值，获取所有实体对象
		/// </summary>
		/// <param name="name">属性</param>
		/// <param name="value">值</param>
		/// <param name="startRowIndex">起始行，0开始</param>
		/// <param name="maximumRows">最大返回行数</param>
		/// <returns>栏目 实体数组</returns>
		[DataObjectMethod(DataObjectMethodType.Select, true)]
		public static IList<Board> SelectAll(String name, Object value, int startRowIndex, int maximumRows)
		{
			if (EnableCache) return FindAllInCache(new String[] { name }, new Object[] { value }, startRowIndex, maximumRows);
			if (String.IsNullOrEmpty(name))
				return SelectAll(null, null, null, startRowIndex, maximumRows);
			else
				return SelectAll(MakeCondition(typeof(Board), new String[] { name }, new Object[] { value }, "And"), null, null, startRowIndex, maximumRows);
		}
		#endregion

		#region 取记录数
		/// <summary>
		/// 返回总记录数
		/// </summary>
		/// <returns></returns>
		public static Int32 SelectCount()
		{
			if (EnableCache) return Cache == null ? 0 : Cache.Count;
			return SelectCount<Board>();
		}

		/// <summary>
		/// 返回总记录数
		/// </summary>
		/// <param name="whereClause">条件，不带Where</param>
		/// <param name="orderClause">排序，不带Order By</param>
		/// <param name="selects">查询列</param>
		/// <param name="startRowIndex">起始行</param>
		/// <param name="maximumRows">最大返回行数</param>
		/// <returns>总行数</returns>
		public static Int32 SelectCount(String whereClause, String orderClause, String selects, int startRowIndex, int maximumRows)
		{
			//如果三个参数都为空，则可以使用缓存
			if (EnableCache && String.IsNullOrEmpty(whereClause) &&
				String.IsNullOrEmpty(orderClause) && String.IsNullOrEmpty(selects))
			{
				IList<Board> list = FindAllInCache(null, null, startRowIndex, maximumRows);
				return list == null ? 0 : list.Count;
			}
			return SelectCount<Board>(whereClause, orderClause, selects, startRowIndex, maximumRows);
		}

		/// <summary>
		/// 根据属性列表以及对应的值列表，返回总记录数
		/// </summary>
		/// <typeparam name="T">实体类型</typeparam>
		/// <param name="names">属性列表</param>
		/// <param name="values">值列表</param>
		/// <returns>总行数</returns>
		protected static Int32 SelectCount(String[] names, Object[] values)
		{
			if (EnableCache)
			{
				IList<Board> list = FindAllInCache(names, values);
				return list == null ? 0 : list.Count;
			}
			return SelectCount(MakeCondition(typeof(Board), names, values, "And"), null, null, 0, 0);
		}

		/// <summary>
		/// 根据属性以及对应的值，返回总记录数
		/// </summary>
		/// <typeparam name="T">实体类型</typeparam>
		/// <param name="name">属性</param>
		/// <param name="value">值</param>
		/// <returns>总行数</returns>
		protected static Int32 SelectCount(String name, Object value)
		{
			return SelectCount(name, value);
		}

		/// <summary>
		/// 根据属性以及对应的值，返回总记录数
		/// </summary>
		/// <typeparam name="T">实体类型</typeparam>
		/// <param name="name">属性</param>
		/// <param name="value">值</param>
		/// <param name="startRowIndex">开始行，0开始</param>
		/// <param name="maximumRows">最大返回行数</param>
		/// <returns>总行数</returns>
		protected static Int32 SelectCount(String name, Object value, int startRowIndex, int maximumRows)
		{
			if (EnableCache)
			{
				IList<Board> list = FindAllInCache(new String[] { name }, new Object[] { value }, startRowIndex, maximumRows);
				return list == null ? 0 : list.Count;
			}

			if (String.IsNullOrEmpty(name))
				return SelectCount(null, null, null, startRowIndex, maximumRows);
			else
				return SelectCount(MakeCondition(typeof(Board), new String[] { name }, new Object[] { value }, "And"), null, null, startRowIndex, maximumRows);
		}
		#endregion

		#region 插入
		/// <summary>
		/// 把一个实体对象持久化到数据库
		/// </summary>
		/// <param name="obj">栏目 实体对象</param>
		/// <returns>返回受影响的行数</returns>
		[DataObjectMethod(DataObjectMethodType.Insert, false)]
		public static Int32 Insert(Board obj)
		{
			return obj.Insert();
		}

		/// <summary>
		/// 把一个实体对象持久化到数据库
		/// </summary>
		/// <param name="names">更新属性列表</param>
		/// <param name="values">更新值列表</param>
		/// <returns>返回受影响的行数</returns>
		[DataObjectMethod(DataObjectMethodType.Insert, false)]
		public static Int32 Insert(String[] names, Object[] values)
		{
			if (!OnInserting()) return -1;
			return OnInserted(Insert<Board>(names, values));
		}
		#endregion

		#region 更新
		/// <summary>
		/// 把一个实体对象更新到数据库
		/// </summary>
		/// <param name="obj">栏目 实体对象</param>
		/// <returns>返回受影响的行数</returns>
		[DataObjectMethod(DataObjectMethodType.Update, false)]
		public static Int32 Update(Board obj)
		{
			return obj.Update();
		}

		/// <summary>
		/// 更新一批实体数据
		/// </summary>
		/// <param name="setClause">要更新的项和数据</param>
		/// <param name="whereClause">指定要更新的实体</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Update, false)]
		public static Int32 Update(String setClause, String whereClause)
		{
			if (!OnUpdating()) return -1;
			return OnUpdated(Update<Board>(setClause, whereClause));
		}

		/// <summary>
		/// 更新一批实体数据
		/// </summary>
		/// <param name="setNames">更新属性列表</param>
		/// <param name="setValues">更新值列表</param>
		/// <param name="whereNames">条件属性列表</param>
		/// <param name="whereValues">条件值列表</param>
		/// <returns>返回受影响的行数</returns>
		[DataObjectMethod(DataObjectMethodType.Update, false)]
		public static Int32 Update(String[] setNames, Object[] setValues, String[] whereNames, Object[] whereValues)
		{
			String sc = MakeCondition(typeof(Board), setNames, setValues, ", ");
			String wc = MakeCondition(typeof(Board), whereNames, whereValues, " And ");
			return Update(sc, wc);
		}
		#endregion

		#region 删除
		/// <summary>
		/// 从数据库中删除指定实体对象。
		/// 实体类应该实现该方法的另一个副本，以唯一键或主键作为参数
		/// </summary>
		/// <param name="obj">栏目 实体对象</param>
		/// <returns>返回受影响的行数，可用于判断被删除了多少行，从而知道操作是否成功</returns>
		[DataObjectMethod(DataObjectMethodType.Delete, false)]
		public static Int32 Delete(Board obj)
		{
			return obj.Delete();
		}

		/// <summary>
		/// 从数据库中删除指定条件的实体对象。
		/// </summary>
		/// <param name="whereClause">限制条件</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Delete, false)]
		public static Int32 Delete(String whereClause)
		{
			if (!OnDeleting()) return -1;
			return OnDeleted(Delete<Board>(whereClause));
		}

		/// <summary>
		/// 从数据库中删除指定属性列表和值列表所限定的实体对象。
		/// </summary>
		/// <param name="names">属性列表</param>
		/// <param name="values">值列表</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Delete, false)]
		public static Int32 Delete(String[] names, Object[] values)
		{
			return Delete(MakeCondition(typeof(Board), names, values, "And"));
		}

		/// <summary>
		/// 根据唯一键ID从数据库中删除指定实体对象。
		/// </summary>
		/// <param name="ID">唯一键</param>
		/// <returns>栏目 实体对象</returns>
		[DataObjectMethod(DataObjectMethodType.Delete, false)]
		public static Int32 DeleteByKey(Int32 __ID)
		{
			return Delete(new String[] { Board._.ID }, new Object[] { __ID });
		}
		#endregion
		#endregion

		#region 属性		
		/// <summary>
		/// 取得字段名的快捷方式
		/// </summary>
		public class _
		{
			/// <summary>
			/// 编号
			/// </summary>
			public const String ID = "ID";
			
			/// <summary>
			/// 栏目
			/// </summary>
			public const String BoardName = "BoardName";
			
			/// <summary>
			/// 父栏目
			/// </summary>
			public const String ParentID = "ParentID";
			
			/// <summary>
			/// 排序
			/// </summary>
			public const String Order = "Order";
			
			/// <summary>
			/// 提示
			/// </summary>
			public const String Tips = "Tips";
			
			/// <summary>
			/// 备注
			/// </summary>
			public const String Readme = "Readme";
		}
		#endregion
	}
}